
package com.joysuch.wwyt.core.common.util;

import org.apache.commons.lang3.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;

public class DateTimeUtil {

    public static final String FORMAT_DEFAULT = "yyyy-MM-dd HH:mm:ss";

    public static final String FORMAT_DEFAULT_DATE = "yyyy-MM-dd";

    /**
     * Date转换为LocalDateTime
     *
     * @param date
     */
    public static LocalDateTime date2LocalDateTime(Date date) {
        Instant instant = date.toInstant();// An instantaneous point on the time-line.(时间线上的一个瞬时点。)
        ZoneId zoneId = ZoneId.systemDefault();// A time-zone ID, such as {@code Europe/Paris}.(时区)
        LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
        return localDateTime;
    }

    /**
     * LocalDateTime转换为Date
     *
     * @param localDateTime
     */
    public static Date localDateTime2Date(LocalDateTime localDateTime) {
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = localDateTime.atZone(zoneId);// Combines this date-time with a time-zone to create a
        // ZonedDateTime.
        Date date = Date.from(zdt.toInstant());
        return date;
    }

    /**
     * 转换字符串到日期对象
     *
     * @param strDate
     * @param format
     * @return
     * @throws ParseException
     */
    public static Date parseDateTime(String strDate, String format) throws ParseException {
        if (format == null) {
            format = FORMAT_DEFAULT;
        }
        return new SimpleDateFormat(format).parse(strDate);
    }

    /**
     * 转换字符串到日期对象
     *
     * @param strDate
     * @return
     * @throws ParseException
     */
    public static Date parseDateTime(String strDate) throws ParseException {
        return parseDateTime(strDate, null);
    }

    public static String formatDate(Date date, String pattern) {
        if (date == null) {
            throw new IllegalArgumentException("input date can not be null.");
        }

        if (pattern == null) {
            pattern = FORMAT_DEFAULT_DATE;
        }

        DateFormat df = new SimpleDateFormat(pattern);
        return df.format(date);
    }

    public static String formatDate(Date date) {
        if (date == null) {
            throw new IllegalArgumentException("input date can not be null.");
        }

        DateFormat df = new SimpleDateFormat(FORMAT_DEFAULT_DATE);
        return df.format(date);
    }

    /**
     * 转换字符串到日期对象
     *
     * @param strDate
     * @return
     * @throws ParseException
     */
    public static Date parseDate(String strDate) throws ParseException {
        return parseDateTime(strDate, FORMAT_DEFAULT_DATE);
    }

    public static Date parseDateV2(String strDate) {
        try {
            return parseDateTime(strDate, FORMAT_DEFAULT_DATE);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date parseDate(String strDate , String format)  {
        if(format == null){
            format = FORMAT_DEFAULT;
        }
        try {
            return  new SimpleDateFormat(format).parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Date->LocalDate
     *
     * @param date
     * @return
     */
    public static LocalDate date2LocalDate(Date date) {
        if (null == date) {
            return null;
        }
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
    }

    /**
     * LocalDate->Date
     *
     * @param localDate
     * @return
     */
    public static Date localDate2Date(LocalDate localDate) {
        if (null == localDate) {
            return null;
        }
        ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
        return Date.from(zonedDateTime.toInstant());
    }

    public static LocalTime String2LocalTime(String str,String foamart) {
        if (StringUtils.isNotBlank(str)) {
            return LocalTime.parse(str, DateTimeFormatter.ofPattern(foamart));
        } else {
            return null;
        }
    }
    public static LocalDate getFirstDayOfCurrentMonth() {
        return getFirstDayOfMonth(LocalDate.now());
    }

    public static LocalDate getFirstDayOfMonth(LocalDate date) {
        return date.with(TemporalAdjusters.firstDayOfMonth());
    }

    public static LocalDate getLastDayOfCurrentMonth() {
        return getLastDayOfMonth(LocalDate.now());
    }

    public static LocalDate getLastDayOfMonth(LocalDate date) {
        return date.with(TemporalAdjusters.lastDayOfMonth());
    }

    public static LocalDate getFirstDayOfCurrentQuarter() {
        return getFirstDayOfQuarter(LocalDate.now());
    }

    public static LocalDate getFirstDayOfQuarter(LocalDate date) {
        date = getFirstDayOfMonth(date);
        while (date.getMonthValue() != 1 && date.getMonthValue() != 4
                && date.getMonthValue() != 7 && date.getMonthValue() != 10) {
            date = date.minusMonths(1);
        }
        return date;
    }
    public static LocalDateTime dateToLocalDateTime(Date date) {
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.systemDefault();
        return LocalDateTime.ofInstant(instant, zone);
    }


    public static LocalDate getLastDayOfCurrentQuarter() {
        return getLastDayOfQuarter(LocalDate.now());
    }

    public static LocalDate getLastDayOfQuarter(LocalDate date) {
        date = getFirstDayOfQuarter(date);
        date = date.plusMonths(2);
        date = getLastDayOfMonth(date);
        return date;
    }

}
